package actors

import (
	"context"
	"fmt"
	proto "xagent/proto/v1"
)

// BaseAction provides a basic implementation of the Action interface
type BaseAction struct {
	name          string
	description   string
	prerequisites []string
	validator     func(interface{}) error
	executor      func(context.Context, interface{}) (*proto.AgentMessage, error)
}

// NewBaseAction creates a new base action
func NewBaseAction(
	name string,
	description string,
	prerequisites []string,
	validator func(interface{}) error,
	executor func(context.Context, interface{}) (*proto.AgentMessage, error),
) *BaseAction {
	if validator == nil {
		validator = func(interface{}) error { return nil }
	}

	return &BaseAction{
		name:          name,
		description:   description,
		prerequisites: prerequisites,
		validator:     validator,
		executor:      executor,
	}
}

// GetName returns the action name
func (a *BaseAction) GetName() string {
	return a.name
}

// GetDescription returns the action description
func (a *BaseAction) GetDescription() string {
	return a.description
}

// GetPrerequisites returns the action prerequisites
func (a *BaseAction) GetPrerequisites() []string {
	prereqs := make([]string, len(a.prerequisites))
	copy(prereqs, a.prerequisites)
	return prereqs
}

// Validate validates the input for this action
func (a *BaseAction) Validate(input interface{}) error {
	if a.validator == nil {
		return nil
	}
	return a.validator(input)
}

// Execute executes the action with the given input
func (a *BaseAction) Execute(ctx context.Context, input interface{}) (*proto.AgentMessage, error) {
	if err := a.Validate(input); err != nil {
		return nil, fmt.Errorf("input validation failed: %w", err)
	}

	if a.executor == nil {
		return nil, fmt.Errorf("no executor defined for action %s", a.name)
	}

	return a.executor(ctx, input)
}

// WithValidator adds a validator function to the action
func (a *BaseAction) WithValidator(validator func(interface{}) error) *BaseAction {
	a.validator = validator
	return a
}

// WithExecutor adds an executor function to the action
func (a *BaseAction) WithExecutor(executor func(context.Context, interface{}) (*proto.AgentMessage, error)) *BaseAction {
	a.executor = executor
	return a
}

// WithPrerequisites adds prerequisites to the action
func (a *BaseAction) WithPrerequisites(prerequisites ...string) *BaseAction {
	a.prerequisites = append(a.prerequisites, prerequisites...)
	return a
}

// HasPrerequisite checks if the action has a specific prerequisite
func (a *BaseAction) HasPrerequisite(prerequisite string) bool {
	for _, p := range a.prerequisites {
		if p == prerequisite {
			return true
		}
	}
	return false
}
